/**
 * Copyright 2015 ABSir's Studio
 * 
 * All right reserved
 *
 * Create on 2015年10月5日 上午11:04:18
 */
package com.absir.appserv.system.service;

import java.net.URLEncoder;
import java.util.Date;
import java.util.Map;

import com.absir.appserv.configure.JConfigureUtils;
import com.absir.appserv.system.bean.JPayTrade;
import com.absir.appserv.system.bean.proxy.JiUserBase;
import com.absir.appserv.system.configure.JOpenConfigure;
import com.absir.appserv.system.configure.JQianbaoConfigure;
import com.absir.appserv.system.helper.HelperClient;
import com.absir.appserv.system.helper.HelperJson;
import com.absir.bean.core.BeanFactoryUtils;
import com.absir.bean.inject.value.Bean;
import com.absir.core.dyna.DynaBinder;
import com.absir.core.kernel.KernelCharset;
import com.absir.core.kernel.KernelDyna;
import com.absir.core.kernel.KernelString;
import com.absir.qianbao.Utils.CoderUtils;

/**
 * @author absir
 *
 */
@Bean
public class QianbaoService implements IPayInterface, IPayOrder {

	/** QIANBAO_CONFIGURE */
	public static final JQianbaoConfigure QIANBAO_CONFIGURE = JConfigureUtils.getConfigure(JQianbaoConfigure.class);

	/** ME */
	public static final QianbaoService ME = BeanFactoryUtils.get(QianbaoService.class);

	/** PLAT_FORM_NAME */
	public static final String PLAT_FORM_NAME = "Qianbao";

	/** queryLoginUrl */
	protected String queryLoginUrl = "http://open.qbao.com/oauth/token";

	/** queryTestLoginUrl */
	protected String queryTestLoginUrl = "http://testopen.qbao.com/oauth/token";

	/** queryUserUrl */
	protected String queryUserUrl = "http://open.qbao.com/unity/user_info";

	/** queryTestUserUrl */
	protected String queryTestUserUrl = "http://testopen.qbao.com/unity/user_info";

	/** orderUrl */
	protected String orderUrl = "https://opensdk.qbao.com/api/v20/grantrequest.html";

	/** testOrderUrl */
	protected String testOrderUrl = "https://testopensdk.qbao.com/api/v20/grantrequest.html";

	/** doOrderUrl */
	protected String doOrderUrl = "https://opensdk.qbao.com/api/v20/queryrequest.html";

	/** testDoOrderUrl */
	protected String testDoOrderUrl = "https://testopensdk.qbao.com/api/v20/queryrequest.html";

	/** payUrl */
	protected String payUrl = "https://opensdk.qbao.com/api/v20/payrequest.html";

	/** testPayUrl */
	protected String testPayUrl = "https://testopensdk.qbao.com/api/v20/payrequest.html";

	protected String queryTestOrderUrl = "https://testopensdk.qbao.com/api/v20/queryrequest.html";

	protected String queryOrderUrl = "https://opensdk.qbao.com/api/v20/queryrequest.html";

	public static class LoginData {

		public String access_token;

		public String token_type;

		public String refresh_token;

		public String expires_in;

		public String scope;

	}

	public static class DataResult {

		public String code;

		public boolean success;

		public Object data;

	}

	public static class UserData {
		public String account;

		public String birthday;

		public String access_token;
	}

	/*
	 * String client_id 申请的应用appid String client_secret 申请的应用appkey String
	 * grant_type 授权方式: 授权码模式。固定值为"authorization_code" String code
	 * 上一个接口的authorization_code redirect_uri与上面一步中传入的redirecturi保持一致
	 */
	public UserData onLoginData(String code) {
		String url = (QIANBAO_CONFIGURE.isTest() ? queryTestLoginUrl : queryLoginUrl) + "?client_id="
				+ QIANBAO_CONFIGURE.getAppid() + "&client_secret=" + QIANBAO_CONFIGURE.getAppSecrect()
				+ "&grant_type=authorization_code&code=" + code + "&redirect_uri=";
		String rest = HelperClient.openConnection(url, false, null, String.class);
		// System.out.println(rest);
		LoginData data = HelperJson.decodeNull(rest, LoginData.class);
		if (data != null && !KernelString.isEmpty(data.access_token)) {
			url = (QIANBAO_CONFIGURE.isTest() ? queryTestUserUrl : queryUserUrl) + "?client_id=" + QIANBAO_CONFIGURE.getAppid()
					+ "&access_token=" + data.access_token;
			DataResult dataResult = HelperClient.openConnection(url, false, null, DataResult.class);
			if (dataResult != null && dataResult.success) {
				UserData userData = DynaBinder.to(dataResult.data, UserData.class);
				if (userData != null && !KernelString.isEmpty(userData.account)) {
					userData.access_token = data.access_token;
					return userData;
				}
			}
		}

		return null;
	}

	/**
	 * @param code
	 * @return
	 */
	public JiUserBase onLoginCode(String code) {
		String url = (QIANBAO_CONFIGURE.isTest() ? queryTestLoginUrl : queryLoginUrl) + "?client_id="
				+ QIANBAO_CONFIGURE.getAppid() + "&client_secret=" + QIANBAO_CONFIGURE.getAppSecrect()
				+ "&grant_type=authorization_code&code=" + code + "&redirect_uri=";
		LoginData data = HelperClient.openConnection(url, false, null, LoginData.class);
		if (data != null && !KernelString.isEmpty(data.access_token)) {
			url = (QIANBAO_CONFIGURE.isTest() ? queryTestUserUrl : queryUserUrl) + "?client_id=" + QIANBAO_CONFIGURE.getAppid()
					+ "&access_token=" + data.access_token;
			DataResult dataResult = HelperClient.openConnection(url, false, null, DataResult.class);
			if (dataResult != null && dataResult.success) {
				UserData userData = DynaBinder.to(dataResult.data, UserData.class);
				if (userData != null && !KernelString.isEmpty(userData.account)) {
					return SecurityService.ME.openUserBase(userData.account, null, PLAT_FORM_NAME);
				}
			}
		}

		return null;
	}

	public static class OrderData {

		public String merchantTransCode;

		public String transDate;

		public String tokenCode;

		public boolean isSuccess;

		public String code;

		public String msg;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.absir.appserv.system.service.IPayOrder#order(com.absir.appserv.system
	 * .bean.JPayTrade, java.util.Map)
	 */
	@Override
	public Object order(JPayTrade payTrade, Map<String, Object> paramMap) throws Exception {
		// TODO Auto-generated method stub
		String transTime = KernelDyna.DATE_FORMAT_FULL.format(new Date());
		String signCode = "merchantTransCode=" + payTrade.getId() + ",merchantCode=" + QIANBAO_CONFIGURE.getPartnerId()
				+ ",transDate=" + transTime;
		signCode = CoderUtils.sign(signCode.getBytes(KernelCharset.UTF8), QIANBAO_CONFIGURE.getRsaSecrect());
		String url = (QIANBAO_CONFIGURE.isTest() ? testOrderUrl : orderUrl) + "?merchantTransCode=" + payTrade.getId()
				+ "&merchantCode=" + QIANBAO_CONFIGURE.getPartnerId() + "&signType=RSA&transDate=" + transTime
				+ "&transType=1010&signCode=" + signCode;
		OrderData orderData = HelperClient.openConnection(url, false, null, OrderData.class);
		if (orderData != null && orderData.isSuccess) {
			payTrade.setPlatformData(orderData.tokenCode);
			return payTrade;
		}

		return null;
	}

	public static class QianBaoPay {

		public String qbTransCode;

		public String merchantTransCode;

		public String checkOutUrl;

		public String transTime;

		public boolean isSuccess;

		public String code;

		public String msg;

	}

	/**
	 * @param payTrade
	 * @param account
	 * @param access_token
	 * @param appSource
	 * @param payScale
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("deprecation")
	public QianBaoPay pay(JPayTrade payTrade, String account, String access_token, String appSource, int payType, float payScale,
			String transIntro) throws Exception {
		String transTime = KernelDyna.DATE_FORMAT_FULL.format(new Date());
		// String tradeId = payTrade.getId().substring(5,
		// payTrade.getId().length());
		String tradeId = String.valueOf(System.currentTimeMillis()) + payTrade.getUid();
		String signCode = "merchantTransCode=" + tradeId + ",merchantCode=" + QIANBAO_CONFIGURE.getAppid() + ",transTime="
				+ transTime;
		signCode = CoderUtils.sign(signCode.getBytes(KernelCharset.UTF8), QIANBAO_CONFIGURE.getRsaSecrect());
		signCode = URLEncoder.encode(signCode);
		String url = (QIANBAO_CONFIGURE.isTest() ? testOrderUrl : orderUrl) + "?merchantTransCode=" + tradeId + "&merchantCode="
				+ QIANBAO_CONFIGURE.getAppid() + "&signType=RSA&transTime=" + transTime + "&transType=1010&signCode=" + signCode;
		OrderData orderData = HelperClient.openConnection(url, false, null, OrderData.class);
		if (orderData != null && orderData.isSuccess) {
			payTrade.setPlatformData(orderData.tokenCode);
			String callbackUrl = JOpenConfigure.OPEN_CONFIGURE.getServerPath() + "/asset/qianbao/notify/" + payTrade.getId();
			String paySuccessUrl = JOpenConfigure.OPEN_CONFIGURE.getServerPath() + "/asset/qianbao/paySuccess";
			int payAmount = (int) (payTrade.getAmount() * 100);
			String passTime = KernelDyna.DATE_FORMAT_FULL.format(new Date(System.currentTimeMillis() + 36000000));
			signCode = "merchantCode=" + QIANBAO_CONFIGURE.getAppid() + ",appSource=" + appSource + ",merchantTransCode=" + tradeId
					+ ",transTime=" + transTime + ",payType=" + payType + ",transAmount=" + payAmount + ",paySuccessUrl="
					+ paySuccessUrl + ",callbackUrl=" + callbackUrl + ",transCloseTime=" + passTime + ",tokenCode="
					+ orderData.tokenCode;
			signCode = CoderUtils.sign(signCode.getBytes(KernelCharset.UTF8), QIANBAO_CONFIGURE.getRsaSecrect());
			signCode = URLEncoder.encode(signCode);
			url = (QIANBAO_CONFIGURE.isTest() ? testPayUrl : payUrl) + "?transType=2010&appSource=" + appSource + "&merchantCode="
					+ QIANBAO_CONFIGURE.getAppid() + "&versionCode=2.0&signType=RSA&merchantTransCode=" + tradeId + "&transTime="
					+ transTime + "&transIntro=" + transIntro + "&payType=" + payType + "&payScale=" + payScale + "&transAmount="
					+ payAmount + "&paySuccessUrl=" + paySuccessUrl + "&callbackUrl=" + callbackUrl + "&transCloseTime=" + passTime
					+ "&tokenCode=" + orderData.tokenCode + "&loginId=" + account + "&loginTokenCode=" + access_token + "&remark="
					+ payTrade.getId() + "&signCode=" + signCode;
			QianBaoPay qianBaoPay = HelperClient.openConnection(url, false, null, QianBaoPay.class);
			return qianBaoPay;
		}

		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.absir.appserv.system.service.IPayInterface#validator(com.absir.appserv
	 * .system.bean.JPayTrade)
	 */
	@Override
	public boolean validator(JPayTrade payTrade) throws Exception {
		return false;
	}

	public static class PayData {

		public String qbTransNum;

		public String transType;

		public String merchantCode;

		public String transNum;
		public String transTime;
		public String transIntro;
		public String payType;

		public String payScale;

		public String status;
		public String code;
	}

	/**
	 * @param payTrade
	 * @param transNum
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("deprecation")
	public PayData validator(String tradeId, String transNum, String tansDate) throws Exception {
		if (tansDate.length() > 8) {
			tansDate = tansDate.substring(0, 8);
		}

		String signCode = "transNum=" + transNum + ",merchantCode=" + QIANBAO_CONFIGURE.getAppid()
				+ ",queryType=2010,transType=3011,transDate=" + tansDate;
		signCode = CoderUtils.sign(signCode.getBytes(KernelCharset.UTF8), QIANBAO_CONFIGURE.getRsaSecrect());
		signCode = URLEncoder.encode(signCode);
		String url = (QIANBAO_CONFIGURE.isTest() ? queryTestOrderUrl : queryOrderUrl) + "?transNum=" + transNum + "&merchantCode="
				+ QIANBAO_CONFIGURE.getAppid() + "&queryType=2010" + "&transType=3011" + "&transDate=" + tansDate
				+ "&signType=RSA&signCode=" + signCode;
		String rest = HelperClient.openConnection(url, false, null, String.class);
		PayData payData = HelperJson.decode(rest, PayData.class);
		return payData;
	}

}
